Fork me on GitHub

30. Substring with Concatenation of All Words

欢迎fork and star:Nowcoder-Repository-github

30. Substring with Concatenation of All Words

题目

 You are given a string, s, and a list of words, words, that are all of the same length. Find all starting indices of substring(s) in s that is a concatenation of each word in words exactly once and without any intervening characters.

For example, given:
s: "barfoothefoobarman"
words: ["foo", "bar"]

You should return the indices: [0,9].
(order does not matter). 

解决该问题的关键是理解清楚要求。
给定一个目标字符串s,一个单词集合words。
要求使得words集合中所有元素连续出现在s中的首位置组成的集合(元素顺序不考虑)。

正如所给实例,目标字符串s: “barfoothefoobarman”
对比单词集合words: [“foo”, “bar”]
我们发现,在pos=0 ~ 5时“barfoo”恰好匹配,则0压入结果vector;
在pos=9 ~ 14时“foobar”恰好匹配,则9压入结果vector;

在理清楚题意后,便可入手程序实现。

解析

  • 思路:主要运用两个map,先用字典将单词存储一遍,去掉重复元素;然后依次遍历字符串,对每一个位置,查看后面的word是否在原字典中,且word个数不能超过原map的个数
1.子字符串包含且仅包含L中所有的单词,顺序无要求。
注意的是:
1.L中单词有可能重复
2.注意"aaa",{"a","a"}的结果是{0,1}的情况,就是每次直往后移动一个字符。

// 30. Substring with Concatenation of All Words
class Solution_30 {
public:
	vector<int> findSubstring(string s, vector<string>& words) {
		vector<int> vec;
		int words_num = words.size();
		int words_len = words[0].size();

		if (s.size()==0||words.size()==0||s.size()<words_num*words_len)
		{
			return vec;
		}

		unordered_map<string, int> mp;
		for (string str:words)
		{
			mp[str]++; //去掉重复元素的words
		}

		for (int i = 0; i < s.size() - words_len*words_num+1;i++)
		{
			unordered_map<string, int> dest;
			int j = 0;
			for (; j < words_num;j++)
			{
				string temp = s.substr(i + j*words_len, words_len);
				dest[temp]++;
				if (!mp.count(temp)||(mp.count(temp)&&dest[temp]>mp[temp]))
				{
					break;
				}
			}
			if (j==words_num)
			{
				vec.push_back(i);
			}
		}
		return vec;
	}
};

题目来源

posted @ 2018-01-27 13:13  ranjiewen  阅读(299)  评论(0编辑  收藏  举报